package com.baidu.infinity.ui.fragment.home.shape

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.Paint
import android.os.Build
import androidx.annotation.RequiresApi
import com.baidu.infinity.model.LayerModel
import com.baidu.infinity.ui.fragment.home.shape.shapes.TextShape
import com.baidu.infinity.ui.util.LayerModelManager
import com.baidu.infinity.ui.util.state.LayerState

class LayerManager private constructor(){
    companion object{
        val instance = LayerManager()
    }
    var mColor: Int = Color.BLACK
    var mStrokeStyle: Paint.Style = Paint.Style.STROKE
    var mStrockSize: Float = 10f
    val layers: ArrayList<Layer> = arrayListOf()
    fun changeColor(hue:Float,sturation: Float,tightness: Float){
        mColor = Color.HSVToColor(floatArrayOf(
            hue,
            sturation,
            tightness
        ))
    }
    var context: Context ?= null
    fun init(context: Context){
        this.context = context
    }

    @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
    fun addLayer(width: Int, height: Int){
        val layer = Layer(layers.size,width,height)
        layers.add(layer)
        LayerModelManager.instance.addLayer(LayerModel(
            layer.id,
            layer.getBitmap(),
            LayerState.SELECTED
        ))
    }
    fun draw(){
        layers.forEach{layer ->
            layer.draw()
        }
    }
    fun removeLayer(id: Int): Boolean{
        layers.forEach{layer ->
            if(layer.id == id){
                LayerModelManager.instance.removeLayer(layers.size - 1 - layers.indexOf(layer))
                layers.remove(layer)
                return true
            }

        }
        return false
    }
    @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
    fun removeFirstLayer(): Boolean{
        if(layers.isNotEmpty()){
            layers.removeLast()
            return true
        }
        return false
    }
    fun removeLayers(){
        layers.clear()
    }
    fun switchLayer(fromId: Int,toId: Int): Boolean{
        val from = getLayerWithId(fromId)
        val to = getLayerWithId(toId)
        if(from != null && to != null){
            val fromIndex = layers.indexOf(from)
            val toIndex = layers.indexOf(to)
            layers[fromIndex] = to
            layers[toIndex] = from

            return true
        }else{
            return false
        }
    }
    fun getCurrentLayer(): Layer?{
        if(layers.isNotEmpty() && LayerModelManager.instance.getCurrentSelectLayerId() != null){
            return getLayerWithId(LayerModelManager.instance.getCurrentSelectLayerId()!!)
        }else{
            return null
        }
    }
    fun getLayersBitmap(): List<Bitmap>{
        val bitmapList = ArrayList<Bitmap>()
        layers.forEach{layer ->
            bitmapList.add(layer.getBitmap())
        }
        return bitmapList
    }

    fun setEndPoint(endX: Float, endY: Float){
        getCurrentLayer()?.setEndPoint(endX,endY)
    }
    fun addShape(shape: BaseShape,startX: Float,startY: Float){
        getCurrentLayer()?.addShape(shape,startX,startY)
    }
    fun drawLayer(){
        getCurrentLayer()?.draw()
    }
    @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
    fun undo(){
        getCurrentLayer()?.undo()
    }
    fun clear(){
        getCurrentLayer()?.clear()
    }
    private fun getLayerWithId(id: Int): Layer?{
        layers.forEach{layer ->
            if(layer.id == id){
                return layer
            }
        }
        return null
    }
    @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
    fun changeText(text: String){
        val shape = getCurrentLayer()!!.shapeList.last as TextShape
        shape.setText(text)
    }
    fun updateSelectedShape(x: Float, y: Float) {
        getCurrentLayer()?.updateSelectedShape(x,y)
    }
    fun calculateSelectLocation(x: Float, y: Float){
        getCurrentLayer()?.calculateSelectLocation(x,y)
    }
    fun updateSelectedShapeColor(x: Float, y: Float) {
        getCurrentLayer()?.updateSelectedShapeColor(x,y)
    }
}